package cn.tedu.rtc.mqtt.config;

import cn.tedu.rtc.mqtt.model.MqttClientOptions;
import cn.tedu.rtc.mqtt.model.MqttProtocolEnum;
import cn.tedu.rtc.mqtt.model.MqttUseEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 *
 */
@Configuration
@Data
@Slf4j
@ConfigurationProperties
public class MqttConfiguration {

    private static Map<MqttUseEnum, MqttClientOptions> mqtt;

    public void setMqtt(Map<MqttUseEnum, MqttClientOptions> mqtt) {
        MqttConfiguration.mqtt = mqtt;
    }

    /**
     * Get the mqtt address of the basic link.
     *
     * @return
     */
    public static String getBasicMqttAddress() {
        return getMqttAddress(getClientOptions());
    }

    /**
     * Get the configuration options of the basic link of the mqtt client.
     *
     * @return
     */
    static MqttClientOptions getClientOptions() {
        if (mqtt.isEmpty()) {
            throw new Error("Please configure the basic mqtt connection parameters first, otherwise application cannot be started.");
        }
        return mqtt.get(MqttUseEnum.CONFIG);
    }

    /**
     * Splice the mqtt address according to the parameters of different clients.
     *
     * @param options
     * @return
     */
    private static String getMqttAddress(MqttClientOptions options) {
        StringBuilder addr = new StringBuilder()
                .append(options.getProtocol().getProtocolAddr())
                .append(options.getHost().trim())
                .append(":")
                .append(options.getPort());
        if ((options.getProtocol() == MqttProtocolEnum.WS || options.getProtocol() == MqttProtocolEnum.WSS)
                && StringUtils.hasText(options.getPath())) {
            addr.append(options.getPath());
        }
        return addr.toString();
    }

    @Bean
    public MqttConnectOptions mqttConnectOptions() {
        MqttClientOptions customizeOptions = getClientOptions();
        log.info(String.valueOf(customizeOptions));
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setServerURIs(new String[]{getBasicMqttAddress()});
        mqttConnectOptions.setUserName(customizeOptions.getUsername());
        mqttConnectOptions.setPassword(StringUtils.hasText(customizeOptions.getPassword()) ?
                customizeOptions.getPassword().toCharArray() : new char[0]);
        mqttConnectOptions.setAutomaticReconnect(true);
        mqttConnectOptions.setKeepAliveInterval(customizeOptions.getKeepalive());
        // mqttConnectOptions.setCleanSession(false);
        // mqttConnectOptions.setConnectionTimeout(customizeOptions.getTimeout());
        return mqttConnectOptions;
    }

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(mqttConnectOptions());
        return factory;
    }
}